home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
mac
/
files
/
t_sys5
/
92052tar.gz
/
920528.tar
/
tcpgate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-02
|
3KB
|
156 lines
/* @(#) $Header: tcpgate.c,v 1.8 91/06/01 22:18:42 deyke Exp $ */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "global.h"
#include "mbuf.h"
#include "netuser.h"
#include "tcp.h"
#include "hpux.h"
#include "buildsaddr.h"
struct dest {
int port;
char *name;
struct dest *next;
};
static struct dest *dests;
/*---------------------------------------------------------------------------*/
static void tcp_send(tcb)
struct tcb *tcb;
{
int cnt;
struct mbuf *bp;
if ((cnt = space_tcp(tcb)) <= 0) {
off_read(tcb->user);
return;
}
if (!(bp = alloc_mbuf(cnt))) return;
cnt = read(tcb->user, bp->data, (unsigned) cnt);
if (cnt <= 0) {
free_p(bp);
off_read(tcb->user);
close_tcp(tcb);
return;
}
bp->cnt = cnt;
send_tcp(tcb, bp);
}
/*---------------------------------------------------------------------------*/
static void tcp_receive(tcb, cnt)
struct tcb *tcb;
int cnt;
{
char buffer[1024];
struct mbuf *bp;
if (tcb->user > 0) {
recv_tcp(tcb, &bp, 0);
while ((cnt = pullup(&bp, buffer, sizeof(buffer))) > 0)
if (write(tcb->user, buffer, (unsigned) cnt) != cnt) {
free_p(bp);
close_tcp(tcb);
return;
}
}
}
/*---------------------------------------------------------------------------*/
static void tcp_ready(tcb, cnt)
struct tcb *tcb;
int cnt;
{
if (tcb->user > 0) on_read(tcb->user, (void (*)()) tcp_send, tcb);
}
/*---------------------------------------------------------------------------*/
static void tcp_state(tcb, old, new)
struct tcb *tcb;
int old, new;
{
int addrlen;
struct dest *dp;
struct sockaddr *addr;
switch (new) {
#ifdef QUICKSTART
case TCP_SYN_RECEIVED:
#else
case TCP_ESTABLISHED:
#endif
log(tcb, "open %s", tcp_port_name(tcb->conn.local.port));
for (dp = dests; dp && dp->port != tcb->conn.local.port; dp = dp->next) ;
if (!dp ||
!(addr = build_sockaddr(dp->name, &addrlen)) ||
(tcb->user = socket(addr->sa_family, SOCK_STREAM, 0)) <= 0 ||
connect(tcb->user, addr, addrlen)) {
close_tcp(tcb);
return;
}
on_read(tcb->user, (void (*)()) tcp_send, tcb);
return;
case TCP_CLOSE_WAIT:
close_tcp(tcb);
return;
case TCP_CLOSED:
if (tcb->user > 0) {
log(tcb, "close %s", tcp_port_name(tcb->conn.local.port));
off_read(tcb->user);
close(tcb->user);
}
del_tcp(tcb);
break;
}
}
/*---------------------------------------------------------------------------*/
int tcpgate1(argc, argv, p)
int argc;
char *argv[];
void *p;
{
char *name;
char buf[80];
struct dest *dp;
struct socket lsocket;
lsocket.address = INADDR_ANY;
lsocket.port = tcp_port_number(argv[1]);
if (argc < 3)
sprintf(name = buf, "loopback:%d", lsocket.port);
else
name = argv[2];
for (dp = dests; dp && dp->port != lsocket.port; dp = dp->next) ;
if (!dp) {
dp = malloc(sizeof(*dp));
dp->port = lsocket.port;
dp->name = 0;
dp->next = dests;
dests = dp;
}
if (dp->name) free(dp->name);
dp->name = strdup(name);
open_tcp(&lsocket, NULLSOCK, TCP_SERVER, 0, tcp_receive, tcp_ready, tcp_state, 0, 0);
return 0;
}